#ifndef __THREAD__
#define __THREAD__
#include <iostream>
#include <cassert>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <functional>
template<class T>
using func_t = std::function<void(T&)>;

template<class T>
class Thread
{
    public:
    void Execute()
    {
        _func(_data);
    }
    public:
    Thread(std::string name , func_t<T> func , T data) : _threadname(name) , _func(func) , _data(data)
    {}
    void join()
    {
        int n = pthread_join(_tid,nullptr);
        assert(!n);
    }
    static void* threadroutine(void* arg)
    {
        Thread* self = static_cast<Thread*>(arg);
        self->Execute();
        return nullptr;
    }
    void Start()
    {
        int n = pthread_create(&_tid,nullptr,threadroutine,this);
        assert(!n);
    }
    private:
        std::string _threadname;
        pthread_t _tid;
        func_t<T> _func;
        T _data;
};
#endif
